package pe.tnova.generic.structure.project.springmvc.soruce;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;

import pe.tnova.generic.structure.project.springmvc.UI.OptionEntidadBean;
import pe.tnova.generic.structure.project.springmvc.generic.GenerarCapaDAO;
import pe.tnova.generic.structure.project.springmvc.generic.GenerarCapaDAOBase;
import pe.tnova.generic.structure.project.springmvc.generic.GenerarCapaServiceMantenimiento;
import pe.tnova.generic.structure.project.springmvc.generic.GenerarDAOBaseConfig;
import pe.tnova.generic.structure.project.springmvc.util.ConstantesTNOVA;
import pe.tnova.generic.structure.project.springmvc.util.PluginUtil;

public class SourceProjectCore {

	private static final Logger LOG = Logger.getLogger(SourceProjectCore.class.getName());

	private IJavaProject javaProject = null;
	private IFolder srcJAVA = null;
	private String strPackageBase = null;
	private ICompilationUnit[] compilationUnit = null;
	private List<ICompilationUnit> listaICompilationUnits = null;

	private SourceProjectCore(IProject project, IJavaProject javaProject, IFolder srcJAVA) {
		this.javaProject = javaProject;
		this.srcJAVA = srcJAVA;
	}

	public static SourceProjectCore getInstance(IProject project, IJavaProject javaProject, IFolder srcJAVA) {
		return new SourceProjectCore(project, javaProject, srcJAVA);
	}

	public void packageBase(String strPackageBase) {
		this.strPackageBase = strPackageBase;
	}

	public boolean existe(String strPackageDominio) throws JavaModelException {
		return existePackage(strPackageBase + ConstantesTNOVA.DONT + strPackageDominio);
	}

	public boolean existePackage(String strpackage) throws JavaModelException {
		IPackageFragment pack = getPackage(strpackage, false);
		return pack.exists();
	}

	public IPackageFragment getPackage(String strpackage, boolean create) throws JavaModelException {
		LOG.info("getPackage :" + strpackage + " create:" + create);
		IPackageFragmentRoot srcFolder = javaProject.getPackageFragmentRoot(srcJAVA);
		IPackageFragment pack = srcFolder.getPackageFragment(strpackage);
		return pack;
	}

	public IPackageFragment createPackate(String strpackage, boolean create) throws JavaModelException {
		LOG.info("createPackate :" + strpackage + " create:" + create);
		IPackageFragmentRoot srcFolder = javaProject.getPackageFragmentRoot(srcJAVA);
		IPackageFragment pack = getPackage(strpackage, create);
		if (!pack.exists()) {
			if (create) {
				pack = srcFolder.createPackageFragment(strpackage, true, null);
				return pack;
			}
		} else {
			return pack;
		}
		return null;
	}

	public void standarDominio() throws Exception {
		LOG.info("Escanenado las entidades");
		String strpackDominio = strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DOMINIO;
		IPackageFragment packDominio = getPackage(strpackDominio, false);
		compilationUnit = packDominio.getCompilationUnits();
		IType[] iTypes = null;
		LOG.info("count compilationUnit:" + compilationUnit.length);
		if (compilationUnit.length > 0) {
			listaICompilationUnits = new ArrayList<ICompilationUnit>();
			for (ICompilationUnit iCompilationUnit : compilationUnit) {
				iTypes = iCompilationUnit.getTypes();
				for (IType iType : iTypes) {
					ITypeHierarchy typeHier = iType.newSupertypeHierarchy(null);
					IType[] superInterfaces = typeHier.getAllInterfaces();
					for (IType iType2 : superInterfaces) {
						if (iType2.getElementName().equals(ConstantesTNOVA.CLASS_ENTIDAD)) {
							LOG.info("Scan Entidad:" + PluginUtil.getNameFile(iCompilationUnit.getElementName()));
							listaICompilationUnits.add(iCompilationUnit);
						}
					}
				}
			}
		} else {
			throw new Exception("No hay clases que extendan de la interfaz " + ConstantesTNOVA.CLASS_ENTIDAD);
		}
	}

	public List<ICompilationUnit> getListaICompilationUnits() {
		return listaICompilationUnits;
	}

	public void setListaICompilationUnits(List<ICompilationUnit> listaICompilationUnits) {
		this.listaICompilationUnits = listaICompilationUnits;
	}

	public void generarCapaDAO(List<OptionEntidadBean> configuracionEntidades) throws JavaModelException {
		GenerarCapaDAO g = null;
		IPackageFragment packIDAO = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO, false);
		IPackageFragment packDAO = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO_IMPL, false);
		for (OptionEntidadBean optionEntidadBean : configuracionEntidades) {
			if (optionEntidadBean.isCheckGeneraCodigoDAO()) {
				g = new GenerarCapaDAO(this, optionEntidadBean, strPackageBase, packIDAO, packDAO);
				g.startGeneric();
			}
		}
	}

	public void generarCapaDAOBASE(List<OptionEntidadBean> configuracionEntidades) throws JavaModelException {
		GenerarCapaDAOBase g = null;
		IPackageFragment packBase = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO_BASE, false);
		IPackageFragment packBaseImpl = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO_BASE_IMPL, false);
		for (OptionEntidadBean optionEntidadBean : configuracionEntidades) {
			if (optionEntidadBean.isCheckGeneraCodigoDAOBASE()) {
				g = new GenerarCapaDAOBase(this, optionEntidadBean, strPackageBase, packBase, packBaseImpl);
				g.startGeneric();
			}
		}
	}

	public void generarDAOBaseConfig(List<OptionEntidadBean> configuracionEntidades) throws JavaModelException {
		GenerarDAOBaseConfig g = null;
		IPackageFragment packBase = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO_BASE, false);
		IPackageFragment packBaseImpl = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_DAO_BASE_IMPL, false);
		g = new GenerarDAOBaseConfig(this, configuracionEntidades, strPackageBase, packBase, packBaseImpl);
		g.startGeneric();

	}

	public void generarCapaService(List<OptionEntidadBean> configuracionEntidades) {
		//capa servicio 
	}

	public void generarCapaServiceMantenimiento(List<OptionEntidadBean> configuracionEntidades) throws JavaModelException {
		GenerarCapaServiceMantenimiento g = null;
		IPackageFragment packBase = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_SERVICE_MNT, false);
		IPackageFragment packBaseImpl = getPackage(strPackageBase + ConstantesTNOVA.DONT + ConstantesTNOVA.PACK_SERVICE_MNT_IMPL, false);
		for (OptionEntidadBean optionEntidadBean : configuracionEntidades) {
			if (optionEntidadBean.isCheckGeneraCodigoSERVICEMant()) {
				g = new GenerarCapaServiceMantenimiento(this, optionEntidadBean, strPackageBase, packBase, packBaseImpl);
				g.startGeneric();
			}			
		}		
	}

}
